#pragma once

namespace Base { namespace Sig {

    class SigIdGenerator
    {
    public:
        SigIdGenerator(const std::string&);
        ~SigIdGenerator();

    public:
        const void* value() const;

    private:
        const void* m_id;
    };

    class Signal
    {
    protected:
        Signal();
        virtual ~Signal();
        
    public:
        // The subclass MUST override the two functions.
        static const void* typeId();
        virtual const void* id() const;

        template<class T>
        Signal* cast();
    };

    template<class T>
    Signal* Signal::cast()
    {
        if (this->id() == T::typeId())
            return this;

        return 0;
    }
    
}}

// Return a new ID.
#define RETURN_NEW_SIG_ID(className)                                \
    static Base::Sig::SigIdGenerator id_of_##className(#className); \
    return id_of_##className.value();

// Return the ID.
#define RETURN_SIG_ID(className)                                    \
    return className::typeId();
